#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <custom_data_type.h>

//static const uint8_t device_id[11] = "10000065c7"; //biteye hw
static const uint8_t device_id[11] = "100002197a"; //biteye mylinux

static const uint8_t device_model[12] = "PSA-B01-CN";

//static const uint8_t api_key[37] = "d6e33a23-c50d-44ce-a624-ab220c214da5";  //biteye hw

static const uint8_t api_key[37] = "c3bcad68-5c50-4c54-aae1-3934b012bf98";  //biteye mylinux

static uint8_t rom_version[9] = "1.1.1";

//static uint8_t distri_server_domain[30] = "cn-disp.coolkit.cc";
static uint8_t distri_server_domain[30] = "54.223.98.144";

static uint32_t distri_server_port = 443; 

static uint8_t long_server_ip[16]="54.223.34.73";

static uint32_t long_server_port = 443;

static int8_t status_led = 0;
static int8_t status_cemara = 0;
static int8_t status_motionMonitor = 0;
static int8_t status_cloudStore = 0;
static int8_t monitor_sens = 0;

int8_t getDeviceInfo(uint8_t *deviceID, uint8_t *apikey)
{
    uint8_t count = 0;
    for(count = 0; count < 11; count++)
    {
	deviceID[count] = device_id[count];
    }
    for(count = 0; count < 37; count++)
    {
	apikey[count] = api_key[count];
    }
    
    return 0;
}

int8_t getDeviceModel(uint8_t *model)
{
    int8_t count = 0;
    for(count = 0; count < 12; count++)
    {
	model[count] = device_model[count];
    }
    return 0;
}

int8_t setupWifiAP(uint8_t *ssid)
{
    /* do nothing , this AP has been done on PC*/
    return 0;
}

int8_t connectToWifi(uint8_t *connect_ssid, uint8_t *password)
{
    /* do nothing, this has been done on PC*/
    return 0;
}

int8_t getConnectWifiInfo(uint8_t *connect_ssid,uint8_t *password)
{
    /* do nothing, this is not need now*/
    return 0;
}

int8_t setDServerInfo(uint8_t *server_name,uint32_t dserver_port)
{
    uint8_t count = 0;
    for(count = 0; count < 30; count++)
    {
	distri_server_domain[count] = server_name[count];
    }
    distri_server_port = dserver_port;
    return 0;
}

int8_t getDServerInfo(uint8_t *server_name,uint32_t *server_port)
{
    uint8_t count = 0;
    for(count = 0; count < 30; count++)
    {
	server_name[count] = distri_server_domain[count];
    }
    *server_port = distri_server_port;
    return 0;
}

int8_t getFWVersion(uint8_t *version)
{
    uint8_t count = 0;
    for(count = 0; count < 9; count++)
    {
	version[count] = rom_version[count];
    }
    return 0;
}

int8_t setLServerInfo(uint8_t *server_name, uint32_t server_port)
{
    uint8_t count = 0;
    for(count = 0; count < 16; count++)
    {
	long_server_ip[count] = server_name[count];
    }
    long_server_port = server_port;
    return 0;
}

int8_t getLServerInfo(uint8_t *server_name,uint32_t *server_port)
{
    uint8_t count = 0;
    for(count = 0; count < 16; count++)
    {
	server_name[count] = long_server_ip[count];
    }
    *server_port = long_server_port;
    return 0;
}

int8_t setConnectWifiInfo(uint8_t *connect_ssid, uint8_t *password)
{
    ;
}

void systemDelayMs(uint32_t ms)
{
    while(ms)
    {
	usleep(1000);
	ms--;
    }
}

int32_t os_get_random(void)
{
    srand(time(NULL));
    return rand();
}

/*
 * @name : setStatusLed
 * @desc : This function is used to turn on/off the status-led function.
 * @param : led_status , 0 == function off. (Not led off)
 *                       1 == function on. (Not led on)
 * @return : 0 if it succeeds, -1 if it fails.
 */
int8_t setStatusLed(uint8_t led_status)
{
    status_led = led_status;
    printf("[%s] status_led :[%d]\n",__FUNCTION__,status_led);
    return 0;
}
/*
 * @name : getStatusLed
 * @desc : This function is used to get status-led's state.
 * @param : none     
 * @return : 0 == led_function_off\n 
 *           1 == led_function_on\n
 *          -1 == operation fails.
 */
int8_t getStatusLed(void)
{
    return status_led;
}
/*
 * @name : setCameraStatus
 * @desc : This function is used to control the video camera.
 * @param : status , 0 == camera go to sleep mode or like.
 *                   1 == camera go to normal working mode.
 * @return : 0 if it succeeds, -1 if it fails.
 */
int8_t setCameraStatus(uint8_t status)
{
    status_cemara = status;
    printf("[%s]update CameraStatus:%d\n",__FUNCTION__,status_cemara);
    return 0;
}

/*
 * @name : getCameraStatus
 * @desc : This function is used to get video camera's state.
 * @param : none    
 * @return : 0 == camera is not in normal working mode.
 *           1 == camera is in normal working mode.
 *          -1 == operation fails.
 */
int8_t getCameraStatus(void)
{
    return status_cemara;
}
/*
 * @name : setMotionMonitorStatus
 * @desc : This function is used to turn on/off the motion monitor.
 * @param : status , 0 == turn_off\n
 *                   1 == turn_on.
 * @return : 0 if it succeeds, -1 if it fails.
 */
int8_t setMotionMonitorStatus(uint8_t status)
{
    status_motionMonitor = status;
    printf("[%s] motion monitor status %d\n",__FUNCTION__,status_motionMonitor);
    return 0;
}

/*
 * @name : getMotionMonitorStatus
 * @desc : This function is used to get the state of motion monitor.
 * @param : none    
 * @return : 0 == turn_off\n 
 *           1 == turn_on\n
 *          -1 == operation fails.
 */
int8_t getMotionMonitorStatus(void)
{
    return status_motionMonitor;
}
/*
 * @name : setCloudStoreStatus
 * @desc : This function is used to control the motion monitor remote storage.
 * @param : status , 0 == turn_off\n
 *                   1 == turn_on.
 * @return : 0 if it succeeds, -1 if it fails.
 */
int8_t setCloudStoreStatus(uint8_t status)
{
    status_cloudStore = status;
    printf("[%s] update status_cloudStore: %d\n",__FUNCTION__,status_cloudStore);
    return 0;
}

/*
 * @name : getCloudStoreStatus
 * @desc : This function is used to get the state of motion monitor remote storage.
 * @param : none    
 * @return : 0 == turn_off\n 
 *           1 == turn_on\n
 *          -1 == operation fails.
 */
int8_t getCloudStoreStatus(void)
{
    return status_cloudStore;
}
/*
 * @name : setMotionMonitorSensitivity
 * @desc : This function is used to control the sensitivity of motion monitor.
 * @param : sensitivity , 0 == low\n
 *                        1 == middle\n
 *                        2 == high.
 * @return : 0 if it succeeds, -1 if it fails.
 */
int8_t setMotionMonitorSensitivity(uint8_t sensitivity)
{
    monitor_sens = sensitivity;
    printf("[%s] update monitor sensitivity: %d\n",__FUNCTION__,monitor_sens);
    return 0;
}

/*
 * @name : getMotionMonitorSensitivity
 * @desc : This function is used to get the sensitivity of motion monitor.
 * @param : none    
 * @return : 0 == low\n 
 *           1 == middle\n
 *           2 == high\n
 *          -1 == operation fails.
 */
int8_t getMotionMonitorSensitivity(void)
{
    return monitor_sens;
}
/*
 * @name : setCloudStoreParam
 * @desc : This function is only used to set the parameters of remote storage. 
 * @param : A point of a buff stored the parameters.
 *          struct cloud_parameters{
 *              unsigned char captureNumber; // 3 -> 3 pictures/once
 *              unsigned char lengthOfVideo; // 20 -> max 20s a video
 *              unsigned char uploadLimit;   // 20 -> 20 minutes time, uploud once
 *              unsigned char storeType;     // 0 -> aws , 1 -> QiNiu 
 *              unsigned char storeAppid[50]; 
 *              unsigned char storeAppSecret[50]; 
 *              unsigned char callbackUrl[128];
 *              unsigned char callbackHost[16];
 *              unsigned char callbackBody[256];
 *              unsigned char bucketName[24]; 
 *              unsigned char persistentPipeline[32];
 *              unsigned char persistentOps[256];
 *              unsigned char persistentNotifyUrl[80];
 *              int deleteAfterDays;
 *          }
 *          Do not change the point itself in this function.
 * @return : 0 if it succeeds, -1 if it fails.
 */
int8_t setCloudStoreParam(void *params)
{
    //printf("[%s] set cloud store params done\n",__FUNCTION__);
    return 0;
}
/*
 * @name : setOtaInfo
 * @desc : This function is only used to update the OTA information.
 *         NOTE that DO NOT excute the OTA process in this function.
 *         The OTA should be excuted sometime after this function is done. 
 * @param : url ,a 125-bit string store the downloud path of the OTA bin file.
 *          digest , a 65-bit string. This is the result of sha256(bin)
 *          sequence, a 14-bit string & only needs to be update after OTA is done.
 *          This sequence needs to be passed to iotgoUpdateOtaDone(unsigned char *sequence).
 *          Do not change the point itself in this function.
 *          
 * @return : 0 if it succeeds, -1 if it fails.
 */
int8_t setOtaInfo(uint8_t *url, uint8_t *digest ,uint8_t *sequence)
{
    printf("[%s] OTA url is %s\n",__FUNCTION__,url);
    printf("[%s] OTA digest is %s\n",__FUNCTION__,digest);
    printf("[%s] OTA sequence is %s\n",__FUNCTION__,sequence);
    return 0;
}
/*
 * @name : getWifiRssi
 * @desc : get the wifi rssi from the platform.\n
 * @param : none
 * @return : rssi num if it succeeds, -1 if it fails.
 */   
int8_t getWifiRssi(void)
{
    return 55;
}

/*
 * @name : getWifiInfo
 * @desc : This function is only used to get the parameters of the WIFI. 
 * @param : A point of a sturct stored the parameters.\n
 *          struct {
 *              unsigned char ip_add[16]; //192.168.200.105
 *              unsigned char mac_add[20];//B0:D5:9D:53:E7:FF 
 *	        }
 *          The ip_add & mac_add are strings.
 *          Just copy the value to the element of the struct in this function. 
 *          Do Not change the pointer.
 * @return : 0 if it succeeds, -1 if it fails.
 */
int8_t getWifiInfo(void *pstruct)
{
    STATION_INFO *p = (STATION_INFO *)pstruct;
    memcpy(p->ip_add,"192.168.200.105",16);
    memcpy(p->mac_add,"B0:D5:9D:53:E7:FF",20);
    return 0;
}


/*
 * @name : getStorageInfo
 * @desc : This function is only used to get the information of storage. 
 * @param : A point of a sturct stored the parameters.\n
 *          struct {
 *	            unsigned int total;   // total 4000 == 4000MB == 4G
 *              unsigned int remain;  // 2000 == 2000MB == 2G remain to be used.
 *	        }
 *          Just copy the value to the element of the struct in this function. 
 *          Do Not change the pointer.
 * @return : 0 if it succeeds, -1 if it fails.
 */
int8_t getStorageInfo(void *pstruct)
{
    STORAGE_INFO *p = (STORAGE_INFO *)pstruct;
    p->total = 4000;
    p->remain = 2000;
    return 0;
}

/*
 * @name : setP2Pinfo
 * @desc : This function is only used to set the P2P's info
 * @param : A point of a buff 
 *          struct p2pInfo{
 *              uint8_t serverName[256];
 *              uint8_t account[64];
 *              uint8_t license[32];
 *          }
 *          Do not change the point itself in this function.
 * @return : 0 if it succeeds, -1 if it fails.
 */
int8_t setP2Pinfo(void *pstruct)
{
    P2P_INFO *info = (P2P_INFO *)pstruct;
    printf("[%s] serverName is [%s]\n",__FUNCTION__,info->serverName);
    printf("[%s] account is [%s]\n",__FUNCTION__,info->account);
    printf("[%s] license is [%s]\n",__FUNCTION__,info->license);
    
    return 0;
}

/*
 * @name : ChangeFlipParam
 * @desc : This function is only used to set the flip info
 * @param : iIsHoriFlip, 1 == yes & 0 == no
 *          iIsVeriFlip, 1 == yes & 0 == no
 * @return : 0 if it succeeds, -1 if it fails.
 */
int ChangeFlipParam(int iIsHoriFlip, int iIsVeriFlip)
{
    printf("[%s] update h_flip -> %d\n",__FUNCTION__,iIsHoriFlip);
    printf("[%s] update v_flip -> %d\n",__FUNCTION__,iIsVeriFlip);
    return 0;
}
